#include "drv_pwm.h"


static TIM_OCInitTypeDef g_oc_init;  // Hold the config for PWM output 


// Config for PWM output 
static void Car_PWM_TIM3_Config() {
    GPIO_InitTypeDef _st_gpio_init;
    TIM_TimeBaseInitTypeDef _st_tb_init;

    // ===== Config GPIO =====
    // TIM3 channel 1, channel 2
    _st_gpio_init.GPIO_Pin = PIN_PWM_A1 | PIN_PWM_A2;
    _st_gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
    _st_gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(PORT_PWM_A, &_st_gpio_init);

    _st_gpio_init.GPIO_Pin = PIN_PWM_B1 | PIN_PWM_B2;
    GPIO_Init(PORT_PWM_B, &_st_gpio_init);

    // ===== Config TIM3 TimeBase =====
    /* -------------------------------------------------------------------------
    TIM3 Configuration:
    TIM3CLK = 72MHz, Prescaler = 0x0, TIM3 counter clock = 72MHz;
    TIM3 ARR Register = 999 => TIM3 Frequency = TIM3 counter clock / (ARR + 1)
    TIM3 Frequency = 72kHz.
    ---------------------------------------------------------------------------- */
    _st_tb_init.TIM_Period = PWM_PERIOD;
    _st_tb_init.TIM_Prescaler = 0;
    _st_tb_init.TIM_ClockDivision = TIM_CKD_DIV1;
    _st_tb_init.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM3, &_st_tb_init);
    
    // ===== Config TIM3 PWM Channels =====
    g_oc_init.TIM_OCMode = TIM_OCMode_PWM1;
    g_oc_init.TIM_OutputState = TIM_OutputState_Enable;
    g_oc_init.TIM_Pulse = PWM_LOW_LEV;
    g_oc_init.TIM_OCPolarity = TIM_OCPolarity_High;
    
    TIM_OC1Init(TIM3, &g_oc_init);
    TIM_OC2Init(TIM3, &g_oc_init);
    TIM_OC3Init(TIM3, &g_oc_init);
    TIM_OC4Init(TIM3, &g_oc_init);
    
//    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);
//    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
//    TIM_OC3PreloadConfig(TIM3, TIM_OCPreload_Enable);
//    TIM_OC4PreloadConfig(TIM3, TIM_OCPreload_Enable);
    
    TIM_Cmd(TIM3, ENABLE);
}


void Car_PWM_Init(void) {
    Car_PWM_TIM3_Config();
}


void Car_PWM_A1_Output(uint16_t ccr_val) {
    g_oc_init.TIM_Pulse = ccr_val;
    TIM_OC1Init(TIM3, &g_oc_init);
}

void Car_PWM_A2_Output(uint16_t ccr_val) {
    g_oc_init.TIM_Pulse = ccr_val;
    TIM_OC2Init(TIM3, &g_oc_init);
}

void Car_PWM_B1_Output(uint16_t ccr_val) {
    g_oc_init.TIM_Pulse = ccr_val;
    TIM_OC3Init(TIM3, &g_oc_init);
}

void Car_PWM_B2_Output(uint16_t ccr_val) {
    g_oc_init.TIM_Pulse = ccr_val;
    TIM_OC4Init(TIM3, &g_oc_init);
}
